#!python

# -*- coding: utf-8 -*-

import cgi
import md5
import os
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from CGIHTTPServer import CGIHTTPRequestHandler


filelist = {}
ofilelist = {}
class MyHandler(CGIHTTPRequestHandler):
    def do_POST(self):
        print self.path + "______POST"
        if self.path.startswith("/file"):
            form = cgi.FieldStorage(fp=self.rfile, headers=self.headers, environ={"REQUEST_METHOD":"POST", "CONTENT_TYPE":self.headers["Content-Type"]})
            print(form)
            type = ""
            path = ""
            size = 0
            seek = 0
            if "type" in form:
                type = cgi.escape(form["type"].value)
            if "file" in form:
                path = cgi.escape(form["file"].value)
            if "size" in form:
                size = int(cgi.escape(form["size"].value))
            if "seek" in form:
                seek = int(cgi.escape(form["seek"].value))
            
            if type == "size":
                if path:
                    size = os.stat(os.path.abspath(os.path.curdir) + "\\" + path).st_size
                    print(size)
                self.wfile.write(size)
            elif type == "get":
                data = ""
                if path and size > 0 and seek >= 0:
                    realpath = os.path.abspath(os.path.curdir) + "\\" + path
                    md5_path = md5.new(realpath).digest()
                    fp = None
                    if md5_path in filelist:
                        fp = filelist[md5_path]
                    else:
                        fp = open(realpath, "rb")
                        filelist[md5_path] = fp
                    if fp:
                        fp.seek(seek)
                        data = fp.read(size)
                self.wfile.write(str(len(data)) + " data " + data)
            elif type == "post":
                data = ""
                if "data" in form:
                    data = form["data"].value
                if path and data:
                    fn = os.path.basename(path).strip("\00")
                    new_filepath = os.path.join("./", "new_" + fn)
                    print("New file: " + new_filepath)
                    md5_path = md5.new(new_filepath).digest()
                    fp = None
                    if md5_path in ofilelist:
                        fp = ofilelist[md5_path]
                    else:
                        fp = open(new_filepath, "wb")
                        ofilelist[md5_path] = fp
                    if fp:
                        #print(data)
                        fp.write(data)
                self.wfile.write("Write OK")
            elif type == "close":
                inout = ""
                if "inout" in form:
                    inout = form["inout"].value
                if path and inout:
                    if inout == "get":
                        realpath = os.path.abspath(os.path.curdir) + "\\" + path
                        md5_path = md5.new(realpath).digest()
                        if md5_path in filelist:
                            filelist[md5_path].close()
                            del filelist[md5_path]
                    elif inout == "post":
                        fn = os.path.basename(path).strip("\00")
                        new_filepath = os.path.join("./", "new_" + fn)
                        print("New file: " + new_filepath)
                        md5_path = md5.new(new_filepath).digest()
                        if md5_path in ofilelist:
                            ofilelist[md5_path].close()
                            del ofilelist[md5_path]
                self.wfile.write("Close OK")
        else:        
            content = CGIHTTPRequestHandler.do_POST(self)
            print content
    def do_GET(self):
        print self.path + "______GET"
        if self.path.startswith("/ws"):
            #for websocket
            self.wfile.write("OK")
        elif self.path.startswith("/file"):
            #for file
            param = {}
            par = self.path.split("?", 1)
            if len(par) > 1:
                par = par[1].split("&")
                for attr in par:
                    if attr.find("=") > 0:
                        attr = attr.split("=")
                        param[attr[0]] = attr[1]
                    else:
                        print("Invalid param: " + attr)
            print(param)
            type = ""
            path = ""
            size = 0
            seek = 0
            if "type" in param:
                type = param["type"]
            if "file" in param:
                path = param["file"]
            if "size" in param:
                size = int(param["size"])
            if "seek" in param:
                seek = int(param["seek"])

            if type == "size":
                if path:
                    size = os.stat(os.path.abspath(os.path.curdir) + "\\" + path).st_size
                    print(size)
                self.wfile.write(size)
            elif type == "get":
                data = ""
                if path and size > 0 and seek >= 0:
                    realpath = os.path.abspath(os.path.curdir) + "\\" + path
                    md5_path = md5.new(realpath).digest()
                    fp = None
                    if md5_path in filelist:
                        fp = filelist[md5_path]
                    else:
                        fp = open(realpath, "rb")
                        filelist[md5_path] = fp
                    if fp:
                        fp.seek(seek)
                        data = fp.read(size)
                self.wfile.write(str(len(data)) + " data " + data)
            elif type == "post":
                data = ""
                if "data" in param:
                    data = param["data"]
                if path and data:
                    fn = os.path.basename(path).strip("\00")
                    new_filepath = os.path.join("./", "new_" + fn)
                    print("New file: " + new_filepath)
                    md5_path = md5.new(new_filepath).digest()
                    fp = None
                    if md5_path in ofilelist:
                        fp = ofilelist[md5_path]
                    else:
                        fp = open(new_filepath, "wb")
                        ofilelist[md5_path] = fp
                    if fp:
                        print(data)
                        fp.write(data)
                self.wfile.write("Write OK")
            elif type == "close":
                inout = ""
                if "inout" in param:
                    inout = param["inout"]
                if path and inout:
                    if inout == "get":
                        realpath = os.path.abspath(os.path.curdir) + "\\" + path
                        md5_path = md5.new(realpath).digest()
                        if md5_path in filelist:
                            filelist[md5_path].close()
                            del filelist[md5_path]
                    elif inout == "post":
                        fn = os.path.basename(path).strip("\00")
                        new_filepath = os.path.join("./", "new_" + fn)
                        print("New file: " + new_filepath)
                        md5_path = md5.new(new_filepath).digest()
                        if md5_path in ofilelist:
                            ofilelist[md5_path].close()
                            del ofilelist[md5_path]
                self.wfile.write("Close OK")
        else:
            CGIHTTPRequestHandler.do_GET(self)
def main():
    try:
        cgiserver = HTTPServer(("", 8080), MyHandler)
        print "use http://localhost:8080 to use cgi server"
        cgiserver.serve_forever()
    except KeyboardInterrupt:
        print "^C receieved, shutting down server..."
        cgiserver.socket.close()

if __name__ == "__main__":
    main()
